package main

import (
	"embed"
	"flag"
	"fmt"
	"os"
	"path"
	"strings"
)

// 定义 一级文件
var levelOneArr = []string{"api", "config", "logger", "router", "service", ".gitignore", "README.md"}

// 定义所有文件路径
var filesArr []string

//go:embed *
var g embed.FS

//go:embed main.go
var m string

func main() {
	projectName := flag.String("p", "", "要创建的 project 名称")
	flag.Parse()

	// 获取 project 名称
	if *projectName == "" {
		panic("projectName is nil")
	}

	// 检查目录是否已存在
	if _, err := os.Stat("./" + *projectName); os.IsExist(err) {
		panic("projectName is exist")
	}

	// 获取要写入的文件 path
	for _, val := range levelOneArr {
		readDir(val)
	}
	// 读取文件内容并写入
	readFile(*projectName)

	// 写入 main1.go
	writeFile(m, *projectName, "main1.go")
}

// 读取一级文件如果是文件夹 则递归获取
func readDir(p string) {
	d, err := g.ReadDir(p)
	if err != nil {
		// 代表不是文件夹
		filesArr = append(filesArr, p)
		return
	}
	for _, val := range d {
		if val.IsDir() {
			readDir(p + "/" + val.Name())
		} else {
			// 记录文件路径
			filesArr = append(filesArr, p+"/"+val.Name())
		}
	}
}

// 读取文件内容
func readFile(projectName string) {
	for _, val := range filesArr {
		fmt.Println("正在写入: ", val)
		content, err := g.ReadFile(val)
		if err != nil {
			panic("读取文件失败" + err.Error())
		}

		// 写入文件
		writeFile(string(content), projectName, val)
	}
}

// 将内容写入文件
func writeFile(content string, projectName string, fileName string) {
	// 使用ReplaceAll函数，替换所有匹配
	newStr := strings.ReplaceAll(content, "module-gin", projectName)

	// 要写入的 路径+文件名
	p := path.Join(".", projectName, fileName)
	// 检查并创建文件目录
	dirMkdirAll(p)

	// 写入文件
	err := os.WriteFile(p, []byte(newStr), 0644)
	if err != nil {
		panic(err)
	}
}

// 检查目录 若目录不存在 自动创建
func dirMkdirAll(fileName string) {
	directory := strings.Split(fileName, "/")
	directory = directory[:len(directory)-1]
	p := path.Join(directory...)
	// 检查目录是否存在
	if _, err := os.Stat(p); os.IsNotExist(err) {
		// 目录不存在，创建目录
		if err := os.MkdirAll(p, 0755); err != nil {
			panic(err)
		}
	}
}
